25.01.30 ISR 적용 및 최적화
마지막 수정일: 2025. 04. 26.
Problem
SSR로 적용을 한 결과 생각보다 너무 로딩시간이 오래걸림
물론 최적화를 시켜서 속도를 줄이는 방법도 존재하겠지만 현재 페이지 내에서 그렇게까지 최적화를 시킬 수 있는 부분이 많지 않아보이고 성능 테스트를 해도 기존 방식 내에서는 나쁘진 않은 성적이 나옴 -> 근본적인 해결 방안 필요
SSR을 적용했을 때 일단 이정도의 성능을 가지고 있었음
물론 이미지 최적화나 폰트 최적화 등 최적화가 많이 이루어지지는 않은 상황이지만 FCP 같은 경우 크게 문제될 정도의 반응은 아니었고 speed index도 양호한 정도라고 생각이 들 수는 있지만 진짜 메모장과 같은 성능을 원했고 그를 위해서는 훨씬 더 빠른 속도를 원했음
해결방안
먼저 빠른 웹사이트들은 어떻게 빠른 반응속도를 가지고 있는지 알아보는 것이 우선이었다.
최적화에 따라 다르겠지만 공통적으로 찾은 부분은 정적 생성을 통해서 만들어진 사이트였다.
하지만 내 블로그 특성상 실시간으로 반영되어야하는 게 가장 처음의 가진 needs중에 하나였고(24.12.17 sync 결정 참고) 이를 지키기 위해서는 정적생성은 불가능하다고 여겨졌다. 이때 찾은 것이 nextjs의 ISR 방식이었고 어느정도 실시간적으로 반영할 수 있으면서 정적페이지의 장점들을 가져갈 수 있다고 하여 바로 도입하였다.
ISR을 도입하면서 잘 정리되어있는 블로그는 Nextjs ISR 설정(app router) 여기에 정리해둠.
ISR도 따로 정리할 예정...\
export const revalidate = 60;
export const dynamicParams = true; // or false, to 404 on unknown paths
export async function generateStaticParams() {
const titles = await getMarkdownTitles();
//do another logic...
return titles.map((title) => ({
md: String(title).split("/"),
})) satisfies PageParams[];
}
실제 사용한 코드의 일부분을 가져왔다. time-based ISR을 이용했으며 사용중인 markdown 제목들을 이용해서 url을 생성하고 있었어서 이를 그대로 가져와 정적 페이지 생성을 진행하였다.
성과
물론 이미지 최적화나 다른 최적화 기법을 도입하긴 했지만 주된 변경점은 SSR -> ISR로 변경한 것이었는데 꽤나 효과가 좋았다. 다음 그림은 최적화 후의 lighthouse 결과이다.
물론 모든 페이지가 아닌 평균으로 나온 페이지 중에서 하나의 사진을 가져온 거긴 하지만 그래도 놀라울 정도로 성능개선이 되었다. 전의 lighthouse 기준으로 개선 전, 후를 정리했을 때는 다음과 같다.
| 항목 | 개선 전 | 개선 후 | 변화량 | 개선율 |
|---|---|---|---|---|
| FCP (First Contentful Paint) | 1.0s | 0.3s | ↓ 0.7s | ↓ 70% |
| LCP (Largest Contentful Paint) | 3.0s | 2.0s | ↓ 1.0s | ↓ 33.3% |
| Speed Index | 2.2s | 0.4s | ↓ 1.8s | ↓ 81.8% |
| TBT (Total Blocking Time) | 90ms | 20ms | ↓ 70ms | ↓ 77.8% |
| CLS (Layout Shift) | 0.082 | 0.003 | ↓ 0.079 | ↓ 96.3% |
물론 모든 페이지의 평균을 냈던 것도 아니어서 성능 측정은 제대로 되어야겠지만 사용자가 한 명인 경우여서 개인적인 만족도를 인용하자면 너무나 만족할만한 사용감이어서 도입 이후 굉장히 만족스러웠다.
필요 개선사항
ISR을 적용하면서 추가적으로 개선해야할 점
- time-based ISR vs on-demand ISR
아직 둘 중에서 어떤 ISR 방식이 내 블로그에 잘 맞을지 모르겠다. 현재 내가 obsidian에서 노트를 저장하고 웹사이트를 보는 방식에 따라서 다를 것 같은데 몇 개월 정도는 내가 직접 써보면서 스타일을 정해가고 그에 맞는 방식에 따라 개발하는 것이 좋아보인다. - LCP 줄이기
개선을 했는데도 불구하고 평균적으로 LCP가 꽤 높게 나온다. 확인해보니 코드를 highlight.js, marked.js를 사용하여 코드에 스타일을 입히는 과정에서 늦게잡히는 거 같은데(뇌피셜) 실제로 웹사이트를 사용하면서는 FCP에 해당하는 속도가 LCP와 동일하다고 느껴질 정도였다. LCP가 저렇게 잡히는 이유가 따로 있는지 따로 제대로 파고드는 시간을 가졌으면 한다.